In [1]:
from pathlib import Path

from ipyniivue import download_dataset

BASE_API_URL_LOCAL = "https://niivue.com/demos/images/"
BASE_API_URL_MODALITIES = "https://niivue.github.io/niivue-demo-images/"
DATA_FOLDER = Path("images")

local_imgs = [
    "FLAIR.nrrd",
    "cactus.nii.gz",
    "DoG.png",
    "anat_final.FT+tlrc.HEAD",
    "mha.mha",
    "template.mif.gz",
    "trix/fa.mif",
    "dsistudio.src.gz",
    "dsistudio.fib.gz",
    "wm.mgz",
]

files_to_download_local = local_imgs.copy()
for img in local_imgs:
    if img.endswith(".HEAD"):
        # Also need to download the paired .BRIK file
        brik_file = img.replace(".HEAD", ".BRIK")
        files_to_download_local.append(brik_file)

download_dataset(
    api_url=BASE_API_URL_LOCAL,
    dest_folder=DATA_FOLDER,
    files=files_to_download_local,
)

modalities_imgs = [
    "chris_MRA",
    "chris_PD",
    "chris_t1",
    "chris_t2",
    "CT_Abdo",
    "CT_AVM",
    "CT_Electrodes",
    "CT_Philips",
    "CT_pitch",
    "fmri_pitch",
    "Iguana",
    "mni152",
    "MR_Gd",
    "pcasl",
    "spm152",
    "spmMotor",
    "visiblehuman",
    "rgb_bmp.jpg",
    "gray_bmp.png",
    "HCD1464653.qsdr.fz",
]

# Add the appropriate extensions
files_to_download_modalities = []
for img in modalities_imgs:
    if (
        not img.endswith(".png")
        and not img.endswith(".jpg")
        and not img.endswith(".fz")
    ):
        img_with_ext = img + ".nii.gz"
    else:
        img_with_ext = img
    files_to_download_modalities.append(img_with_ext)

download_dataset(
    api_url=BASE_API_URL_MODALITIES,
    dest_folder=DATA_FOLDER,
    files=files_to_download_modalities,
)
Downloading FLAIR.nrrd...
Downloading cactus.nii.gz...
Downloading DoG.png...
Downloading anat_final.FT+tlrc.HEAD...
Downloading mha.mha...
Downloading template.mif.gz...
Downloading trix/fa.mif...
dsistudio.src.gz already exists.
Downloading dsistudio.fib.gz...
Downloading wm.mgz...
Downloading anat_final.FT+tlrc.BRIK...
Dataset downloaded successfully to images.
Downloading chris_MRA.nii.gz...
Downloading chris_PD.nii.gz...
Downloading chris_t1.nii.gz...
Downloading chris_t2.nii.gz...
Downloading CT_Abdo.nii.gz...
Downloading CT_AVM.nii.gz...
Downloading CT_Electrodes.nii.gz...
Downloading CT_Philips.nii.gz...
Downloading CT_pitch.nii.gz...
Downloading fmri_pitch.nii.gz...
Downloading Iguana.nii.gz...
mni152.nii.gz already exists.
Downloading MR_Gd.nii.gz...
pcasl.nii.gz already exists.
Downloading spm152.nii.gz...
spmMotor.nii.gz already exists.
Downloading visiblehuman.nii.gz...
Downloading rgb_bmp.jpg...
Downloading gray_bmp.png...
Downloading HCD1464653.qsdr.fz...
Dataset downloaded successfully to images.
In [2]:
import ipywidgets as widgets
from IPython.display import display

from ipyniivue import NiiVue

local_imgs = [
    "FLAIR.nrrd",
    "cactus.nii.gz",
    "DoG.png",
    "anat_final.FT+tlrc.HEAD",
    "mha.mha",
    "template.mif.gz",
    "trix/fa.mif",
    "dsistudio.src.gz",
    "dsistudio.fib.gz",
    "wm.mgz",
]

modalities_imgs = [
    "chris_MRA",
    "chris_PD",
    "chris_t1",
    "chris_t2",
    "CT_Abdo",
    "CT_AVM",
    "CT_Electrodes",
    "CT_Philips",
    "CT_pitch",
    "fmri_pitch",
    "Iguana",
    "mni152",
    "MR_Gd",
    "pcasl",
    "spm152",
    "spmMotor",
    "visiblehuman",
    "rgb_bmp.jpg",
    "gray_bmp.png",
    "HCD1464653.qsdr.fz",
]

# Setup NiiVue Instance

v = NiiVue(
    back_color=(0.7, 0.7, 0.9, 1),
)
v.opts.is_colorbar = True
v.set_slice_type("RENDER")
v.set_clip_plane(0.35, 270, 0)

initial_volume_path = DATA_FOLDER / "mni152.nii.gz"
v.load_volumes(
    [
        {
            "path": initial_volume_path,
            "colormap": "gray",
            "opacity": 1,
            "visible": True,
        }
    ]
)

# Store image paths

img_paths = {}

# Formats
for img in local_imgs:
    img_path = DATA_FOLDER / img
    img_paths[img] = img_path
    if img.endswith(".HEAD"):
        # Also map the paired .BRIK file
        brik_file = img.replace(".HEAD", ".BRIK")
        brik_path = DATA_FOLDER / brik_file
        img_paths[img + "_paired"] = brik_path

# Modalities
for img in modalities_imgs:
    if (
        not img.endswith(".png")
        and not img.endswith(".jpg")
        and not img.endswith(".fz")
    ):
        img_with_ext = img + ".nii.gz"
    else:
        img_with_ext = img
    img_path = DATA_FOLDER / img_with_ext
    img_paths[img] = img_path

# Dropdowns

# Dropdown for Formats
formats_dropdown = widgets.Dropdown(
    options=[(img, img) for img in local_imgs],
    description="Formats:",
    value=None,
)

# Dropdown for Modalities
modalities_dropdown = widgets.Dropdown(
    options=[(img, img) for img in modalities_imgs],
    description="Modalities:",
    value=None,
)

# Dropdown for Colormaps
colormaps = sorted(v.colormaps())
colormap_dropdown = widgets.Dropdown(
    options=colormaps,
    description="Colormap:",
    value="gray",
)

# Event handlers


def on_format_change(change):
    """Handle selection in Formats Dropdown."""
    selected_img = change["new"]
    if not selected_img:
        return
    img_path = img_paths.get(selected_img)
    if not img_path.exists():
        print(f"Image {img_path} not found.")
        return
    volumeObj = {
        "path": img_path,
        "colormap": "gray",
        "opacity": 1,
    }
    if selected_img.endswith(".HEAD"):
        paired_img_path = img_paths.get(selected_img + "_paired")
        if not paired_img_path or not paired_img_path.exists():
            print(f"Paired image {paired_img_path} not found.")
            return
        volumeObj["paired_img_path"] = paired_img_path
    print("Loading format image:", img_path.name)
    v.load_volumes([volumeObj])
    # Reset Modalities Dropdown
    modalities_dropdown.unobserve(on_modality_change, names="value")
    modalities_dropdown.value = None
    modalities_dropdown.observe(on_modality_change, names="value")
    # Update colormap
    if v.volumes:
        colormap_dropdown.value = v.volumes[0].colormap


def on_modality_change(change):
    """Handle selection in Modalities Dropdown."""
    selected_img = change["new"]
    if not selected_img:
        return
    img_path = img_paths.get(selected_img)
    if not img_path.exists():
        print(f"Image {img_path} not found.")
        return
    volumeObj = {
        "path": img_path,
        "colormap": "gray",
        "opacity": 1,
    }
    print("Loading modality image:", img_path.name)
    v.load_volumes([volumeObj])
    # Reset Formats Dropdown
    formats_dropdown.unobserve(on_format_change, names="value")
    formats_dropdown.value = None
    formats_dropdown.observe(on_format_change, names="value")
    # Update colormap
    if v.volumes:
        colormap_dropdown.value = v.volumes[0].colormap


def on_colormap_change(change):
    """Handle selection in Colormap Dropdown."""
    selected_cmap = change["new"]
    if v.volumes:
        v.set_colormap(v.volumes[0].id, selected_cmap)


# Observe the dropdowns

formats_dropdown.observe(on_format_change, names="value")
modalities_dropdown.observe(on_modality_change, names="value")
colormap_dropdown.observe(on_colormap_change, names="value")

# Display all

controls = widgets.VBox(
    [
        formats_dropdown,
        modalities_dropdown,
        colormap_dropdown,
    ]
)

display(controls, v)
/home/runner/work/ipyniivue/ipyniivue/src/ipyniivue/widget.py:1327: UserWarning: Ignored unsupported kwargs in Volume: ['visible']
  volume_objects.append(Volume(**item))